package com.icebergteam.warfacewidget.rank.data;

import java.io.IOException;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.json.JSONObject;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import com.icebergteam.warfacewidget.AppManager;
import com.icebergteam.warfacewidget.WidgetProvider;
import com.icebergteam.warfacewidget.core.LogManager;
import com.icebergteam.warfacewidget.core.Parser;
import com.icebergteam.warfacewidget.core.ParserException;
import com.icebergteam.warfacewidget.core.connection.NetworkManager;
import com.icebergteam.warfacewidget.core.utils.ViewUtils;
import com.icebergteam.warfacewidget.data.sql.UserRankTable;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.SQLException;

public class TopUsersParser extends Parser  {
	final public static String className = TopUsersParser.class.getCanonicalName();
	
	JSONObject doc;
	private String url;
	LinkedHashMap<String, String> paramsList;
	private TopUsersItem topUsersItem = new TopUsersItem();
		
	public TopUsersParser(boolean restoreKey) {
		super(restoreKey);
	}

	public TopUsersParser() {
		super();
	}
	
	public TopUsersParser(String url) {
		super();
		this.url = url;
		paramsList = decodeUrlParameters(url);
	}
	
	
	@Override
	public int saveData(String url) throws Exception, ParserException, SQLException {
		try {
			this.url = url;
			if(paramsList == null || paramsList != null && paramsList.isEmpty()){
				paramsList = decodeUrlParameters(url);
			}
			if (this.isRestoreKey() && AppManager.getDatabase().getUserRankTable().existsUser(Integer.parseInt(paramsList.get("id")), (Integer.parseInt(paramsList.get("server"))))){
				LogManager.LogV(TopUsersParser.className, LogManager.getExecuteMethodName(),
						"generate restore");
				throw new Exception(WidgetProvider.RESTORE_ACTION); 
			}
			LogManager.LogVA(TopUsersParser.className, url);
			this.setRestoreKey(false);
			
			this.doc = NetworkManager.getJSON(this.url);
			this.topUsersItem =  parseXML(this.doc, -1);

			this.stateRequest = TopUsersParser.REQUEST_COMPLETED;
			LogManager.LogV(TopUsersParser.className,  LogManager.getExecuteMethodName(), url);

		} catch (SocketTimeoutException e) {
			restore(Parser.REQUEST_FAILED | Parser.LIST_RESTORED,
										Parser.REQUEST_FAILED | TopUsersParser.LIST_RESTORED);
			throw new ParserException(ViewUtils.getErrorMessage(e), this.stateRequest);
		} catch (IOException e) {
			restore(Parser.REQUEST_FAILED | Parser.LIST_RESTORED,
								TopUsersParser.REQUEST_FAILED);
			throw new ParserException(ViewUtils.getErrorMessage(e), this.stateRequest);
		}catch (SQLException e) {
			this.stateRequest = Parser.DB_INVALID;
			throw new ParserException(ViewUtils.getErrorMessage(e), this.stateRequest);
			
		}catch (Exception e) {
			if (WidgetProvider.RESTORE_ACTION.equals(e.getMessage())) {
				restore(Parser.LIST_RESTORED, Parser.REQUEST_FAILED);
			}
			else{
				this.stateRequest = (Parser.REQUEST_FAILED);
			}
			
			throw new ParserException(ViewUtils.getErrorMessage(e), this.stateRequest);
		}
		return this.stateRequest;
	}
	@Override
	protected void restore(int complete, int failed)	throws Exception {
		try {
			boolean exists = AppManager.getDatabase().getUserRankTable().existsUser(Integer.parseInt(paramsList.get("id")), (Integer.parseInt(paramsList.get("server"))));
			
			if(!exists){
				throw new Exception( LogManager.getExecuteMethodName() + " - DB empty");
			}
			this.stateRequest = complete;
			LogManager.LogV(TopUsersParser.className,  LogManager.getExecuteMethodName());
		}catch (SQLException e) {
			throw new SQLException(String.format(
					"%s - error = %s",  LogManager.getExecuteMethodName(), ViewUtils.getErrorMessage(e)));
		}catch (Exception e1) {
			this.stateRequest = failed;
			throw new Exception(String.format(
					"%s - error = %s",  LogManager.getExecuteMethodName(),ViewUtils.getErrorMessage(e1)));
		}
	}
	
	@Override
	public ArrayList<Object> parseXML(Document doc, int limit) throws Exception {
		return null;
	}
	
	@Override
	protected Object getItem(Element elem) throws Exception{
		return null;
	}

	public  static LinkedHashMap<String, String> decodeUrlParameters(String s)	 {
		 LinkedHashMap<String, String> params = new LinkedHashMap<String, String>();
		 try {
			List<NameValuePair> paramsList =  URLEncodedUtils.parse(new URI(s), "UTF-8");
			for(NameValuePair pair: paramsList){
				 params.put(pair.getName(), pair.getValue());
			}
		 }catch(Exception e) {
			 e.printStackTrace();
		 }
		 return params;
	 }
	
	@Override
	public TopUsersItem parseXML(JSONObject doc, int limit) throws Exception {
		try {
			if(url.isEmpty()){
				throw new Exception("empty url");
			}
			
			
			TopUsersItem item = new TopUsersItem();
			
			
			
			item.setId(Integer.parseInt(paramsList.get("id")));
			item.setName(doc.getString("name"));
			item.setClansRating(doc.getInt("top"));
			item.setRank(doc.getInt("rank"));
			item.setUserRating(doc.getInt("user"));
			item.setMonthRating(doc.getInt("month"));
			item.setServer(Integer.parseInt(paramsList.get("server")));
			
			ContentValues dataToInsert = new ContentValues();    
			dataToInsert.put(UserRankTable.FIELD_ID, item.getId());
			dataToInsert.put(UserRankTable.FIELD_NAME, item.getName());
			dataToInsert.put(UserRankTable.FIELD_RANK, item.getRank());
			dataToInsert.put(UserRankTable.FIELD_USER_RATING, item.getUserRating());
			dataToInsert.put(UserRankTable.FIELD_MONTH_RATING, item.getMonthRating());
			dataToInsert.put(UserRankTable.FIELD_CLANS_RATING, item.getClansRating());
			dataToInsert.put(UserRankTable.FIELD_PUBDATE,  new Date().getTime());
			dataToInsert.put(UserRankTable.FIELD_SERVER,  String.format("%s", item.getServer()));
			
			AppManager.getDatabase().getUserRankTable().updateOrInsert(dataToInsert);
			
			
			
			LogManager.LogEA(className,  doc, item);
			
			return item;
		} 
		catch (Exception e) {
			this.stateRequest = TopUsersParser.XML_INVALID;

			throw new ParserException(String.format(
					"%s - doc = %s; error = %s",  LogManager.getExecuteMethodName(), (doc == null) ? doc == null :"yes", ViewUtils.getErrorMessage(e)), this.stateRequest);
		}
	}

	public TopUsersItem getTopUsersItem() {
		return this.topUsersItem;
	}
	
	

}